package com.sws.capture.service.impl;


import com.sws.attendance.domain.StuAttendance;
import com.sws.attendance.mapper.StuAttendanceMapper;
import com.sws.capture.domain.CapRecord;
import com.sws.capture.domain.CaptureDto;
import com.sws.capture.mapper.CapRecordMapper;
import com.sws.capture.service.CapRecordService;
import com.sws.common.utils.DateUtils;
import com.sws.common.utils.StringUtils;
import com.sws.device.domain.DevDevice;
import com.sws.device.mapper.DevDeviceMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class CapRecordServiceImpl implements CapRecordService {

    @Autowired
    private CapRecordMapper capRecordMapper;

    @Value("${camera.server.photo-prefix}")
    private String jpegUrlPrefix;

    @Autowired
    private DevDeviceMapper devDeviceMapper;

    @Autowired
    private StuAttendanceMapper stuAttendanceMapper;
    
    // 考勤时间配置
    @Value("${attendance.morning.open-start}")
    private String morningOpenStart;
    
    @Value("${attendance.morning.open-end}")
    private String morningOpenEnd;
    
    @Value("${attendance.morning.normal-end}")
    private String morningNormalEnd;
    
    @Value("${attendance.morning.late-start}")
    private String morningLateStart;
    
    @Value("${attendance.morning.late-end}")
    private String morningLateEnd;
    
    @Value("${attendance.noon.open-start}")
    private String noonOpenStart;
    
    @Value("${attendance.noon.open-end}")
    private String noonOpenEnd;
    
    @Value("${attendance.afternoon.open-start}")
    private String afternoonOpenStart;
    
    @Value("${attendance.afternoon.open-end}")
    private String afternoonOpenEnd;
    
    @Value("${attendance.afternoon.normal-end}")
    private String afternoonNormalEnd;
    
    @Value("${attendance.afternoon.late-start}")
    private String afternoonLateStart;
    
    @Value("${attendance.afternoon.late-end}")
    private String afternoonLateEnd;
    
    @Value("${attendance.evening.open-start}")
    private String eveningOpenStart;
    
    @Value("${attendance.evening.open-end}")
    private String eveningOpenEnd;

    @Override
    public boolean faceCapture(CaptureDto captureDto) {
        CapRecord capRecord = new CapRecord();
        BeanUtils.copyProperties(captureDto, capRecord);

        // 确保时间转换正确并使用北京时区
        if (captureDto.getTime() != null) {
            capRecord.setTime(LocalDateTime.ofInstant(
                    Instant.ofEpochSecond(captureDto.getTime()),
                    ZoneId.of("Asia/Shanghai") // 使用北京时区
            ));
        }

        // 确保pid被正确设置
        if (captureDto.getPid() != null && !captureDto.getPid().isEmpty()) {
            capRecord.setPid(captureDto.getPid());
        }

        // 设置图片URL
        Map<String, String> data = captureDto.getData();
        if (data != null) {
            capRecord.setJpegUrlRcg(data.get("jpeg_url_rcg"));
            capRecord.setJpegUrlFace(data.get("jpeg_url_face"));
            capRecord.setJpegUrlBody(data.get("jpeg_url_body"));
            capRecord.setJpegUrlFrame(data.get("jpeg_url_frame"));
        }

        int i = capRecordMapper.insertCapRecord(capRecord);
        return i > 0;
    }

    /**
     * 查询人脸抓拍记录
     *
     * @param id 人脸抓拍记录主键
     * @return 人脸抓拍记录
     */
    @Override
    public CapRecord selectCapRecordById(Integer id) {
        // 设置图片URL
        CapRecord capRecord = capRecordMapper.selectCapRecordById(id);
        setURl(capRecord);
        return capRecord;
    }

    /**
     * 查询人脸抓拍记录列表
     *
     * @param capRecord 人脸抓拍记录
     * @return 人脸抓拍记录
     */
    @Override
    public List<CapRecord> selectCapRecordList(CapRecord capRecord) {
        // 设置图片URL
        List<CapRecord> capRecords = capRecordMapper.selectCapRecordList(capRecord);
        capRecords.forEach(this::setURl);
        return capRecords;
    }


    /**
     * 更新CapRecord对象中的多个JPEG URL字段。
     * 对每个非空的URL字段，将其路径中的"/progs/html"部分替换为设备IP地址的URL前缀。
     * 该操作会直接修改传入的CapRecord对象。
     *
     * @param capRecord 需要修改URL的CapRecord对象，包含原始URL字段
     */
    private void setURl(CapRecord capRecord) {
        if (capRecord == null) {
            return;
        }
        
        // 获取设备SN
        String sn = capRecord.getSn();
        if (StringUtils.isEmpty(sn)) {
            return;
        }
        
        // 根据SN获取设备信息
        DevDevice device = devDeviceMapper.selectDevDeviceBySn(sn);
        String ipPrefix = jpegUrlPrefix; // 默认使用配置的前缀
        
        // 如果找到设备且IP不为空，则使用设备IP构建URL前缀
        if (device != null && StringUtils.isNotEmpty(device.getIp())) {
            ipPrefix = "http://" + device.getIp();
        }
        
        // 处理识别结果图URL
        String jpegUrlRcg = capRecord.getJpegUrlRcg();
        if (StringUtils.isNotEmpty(jpegUrlRcg)) {
            capRecord.setJpegUrlRcg(jpegUrlRcg.replace("/progs/html", ipPrefix));
        }

        // 处理人脸图URL
        String jpegUrlFace = capRecord.getJpegUrlFace();
        if (StringUtils.isNotEmpty(jpegUrlFace)) {
            capRecord.setJpegUrlFace(jpegUrlFace.replace("/progs/html", ipPrefix));
        }

        // 处理人体图URL
        String jpegUrlBody = capRecord.getJpegUrlBody();
        if (StringUtils.isNotEmpty(jpegUrlBody)) {
            capRecord.setJpegUrlBody(jpegUrlBody.replace("/progs/html", ipPrefix));
        }

        // 处理场景图URL
        String jpegUrlFrame = capRecord.getJpegUrlFrame();
        if (StringUtils.isNotEmpty(jpegUrlFrame)) {
            capRecord.setJpegUrlFrame(jpegUrlFrame.replace("/progs/html", ipPrefix));
        }
    }


    /**
     * 新增人脸抓拍记录
     *
     * @param capRecord 人脸抓拍记录
     * @return 结果
     */
    @Override
    public int insertCapRecord(CapRecord capRecord) {
        capRecord.setCreateTime(DateUtils.getNowDate());
        return capRecordMapper.insertCapRecord(capRecord);
    }

    /**
     * 修改人脸抓拍记录
     *
     * @param capRecord 人脸抓拍记录
     * @return 结果
     */
    @Override
    public int updateCapRecord(CapRecord capRecord) {
        capRecord.setUpdateTime(DateUtils.getNowDate());
        return capRecordMapper.updateCapRecord(capRecord);
    }

    /**
     * 批量删除人脸抓拍记录
     *
     * @param ids 需要删除的人脸抓拍记录主键
     * @return 结果
     */
    @Override
    public int deleteCapRecordByIds(Integer[] ids) {
        return capRecordMapper.deleteCapRecordByIds(ids);
    }

    /**
     * 删除人脸抓拍记录信息
     *
     * @param id 人脸抓拍记录主键
     * @return 结果
     */
    @Override
    public int deleteCapRecordById(Integer id) {
        return capRecordMapper.deleteCapRecordById(id);
    }


    /**
     * 联查设备表，进行记录
     *
     * @param stuAttendance
     * @return
     */
    @Override
    public StuAttendance faceCaptureDevice(StuAttendance stuAttendance) {
        DevDevice devDevice = devDeviceMapper.selectDevDeviceBySn(stuAttendance.getSn());
        stuAttendance.setLocation(devDevice.getLocation());
        return stuAttendance;
    }

    /**
     * 处理抓拍图片数据，提取考勤信息
     * 根据时间段判断签到类型和状态
     * 优先检查学生是否已在当前时间段签到，避免重复签到导致状态变更
     *
     * @param captureDto 人脸抓拍数据
     * @param stuAttendance 学生考勤记录
     * @return 处理后的学生考勤记录
     */
    @Override
    public StuAttendance stuAttendanceMsgprocess(CaptureDto captureDto, StuAttendance stuAttendance) {
        // 获取当前抓拍时间
        Date captureTime = new Date(captureDto.getTime() * 1000);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(captureTime);
        
        // 获取当前时间的小时和分钟
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        String currentTime = String.format("%02d:%02d", hour, minute);
        
        // 定义时间格式解析器
        DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
        LocalTime currentLocalTime = LocalTime.parse(currentTime, timeFormatter);
        
        // 查询学生当天的考勤记录
        StuAttendance existingRecord = stuAttendanceMapper.selectStuAttendanceByPidAndRecordDate(
                captureDto.getPid(), stuAttendance.getRecordDate());


        // 如果存在记录，则使用现有记录，避免重复签到覆盖原有状态
        if (existingRecord != null) {
            // 早晨签到判断 (07:50-08:40)
            if (isInTimeRange(currentLocalTime, morningOpenStart, morningOpenEnd)) {
                // 如果学生已经在早上签到过（状态不为0），则保留原有状态，不再更新
                if (existingRecord.getMorningSignIn() != null && existingRecord.getMorningSignIn() != 0) {
                    return existingRecord;
                }
            }
            // 中午签退判断 (11:45-13:00)
            else if (isInTimeRange(currentLocalTime, noonOpenStart, noonOpenEnd)) {
                // 如果学生已经在中午签退过（状态不为0），则保留原有状态，不再更新
                if (existingRecord.getNoonSignOut() != null && existingRecord.getNoonSignOut() != 0) {
                    return existingRecord;
                }
            }
            // 下午签到判断 (13:50-14:40)
            else if (isInTimeRange(currentLocalTime, afternoonOpenStart, afternoonOpenEnd)) {
                // 如果学生已经在下午签到过（状态不为0），则保留原有状态，不再更新
                if (existingRecord.getAfternoonSignIn() != null && existingRecord.getAfternoonSignIn() != 0) {
                    return existingRecord;
                }
            }
            // 晚上签退判断 (17:50-22:00)
            else if (isInTimeRange(currentLocalTime, eveningOpenStart, eveningOpenEnd)) {
                // 如果学生已经在晚上签退过（状态不为0），则保留原有状态，不再更新
                if (existingRecord.getEveningSignOut() != null && existingRecord.getEveningSignOut() != 0) {
                    return existingRecord;
                }
            }
            
            // 如果该时间段未签到，则使用已有记录的ID，确保更新而不是插入
            stuAttendance.setId(existingRecord.getId());
            
            // 保留其他时间段的签到状态，避免覆盖
            if (stuAttendance.getMorningSignIn() == null && existingRecord.getMorningSignIn() != null) {
                stuAttendance.setMorningSignIn(existingRecord.getMorningSignIn());
                stuAttendance.setMorningSignInTime(existingRecord.getMorningSignInTime());
            }
            
            if (stuAttendance.getNoonSignOut() == null && existingRecord.getNoonSignOut() != null) {
                stuAttendance.setNoonSignOut(existingRecord.getNoonSignOut());
                stuAttendance.setNoonSignOutTime(existingRecord.getNoonSignOutTime());
            }
            
            if (stuAttendance.getAfternoonSignIn() == null && existingRecord.getAfternoonSignIn() != null) {
                stuAttendance.setAfternoonSignIn(existingRecord.getAfternoonSignIn());
                stuAttendance.setAfternoonSignInTime(existingRecord.getAfternoonSignInTime());
            }
            
            if (stuAttendance.getEveningSignOut() == null && existingRecord.getEveningSignOut() != null) {
                stuAttendance.setEveningSignOut(existingRecord.getEveningSignOut());
                stuAttendance.setEveningSignOutTime(existingRecord.getEveningSignOutTime());
            }
        }
        
        // 根据当前时间段更新考勤状态
        // 早晨签到判断 (07:50-08:40)
        if (isInTimeRange(currentLocalTime, morningOpenStart, morningOpenEnd)) {
            // 正常签到 (07:50-08:20)
            if (isInTimeRange(currentLocalTime, morningOpenStart, morningNormalEnd)) {
                stuAttendance.setMorningSignIn(1); // 正常签到
            }
            // 迟到 (08:20-08:40)
            else if (isInTimeRange(currentLocalTime, morningLateStart, morningLateEnd)) {
                stuAttendance.setMorningSignIn(2); // 迟到
            }
            stuAttendance.setMorningSignInTime(captureTime);
        }
        
        // 中午签退判断 (11:45-13:00)
        else if (isInTimeRange(currentLocalTime, noonOpenStart, noonOpenEnd)) {
            stuAttendance.setNoonSignOut(1); // 正常签退
            stuAttendance.setNoonSignOutTime(captureTime);
        }
        
        // 下午签到判断 (13:50-14:40)
        else if (isInTimeRange(currentLocalTime, afternoonOpenStart, afternoonOpenEnd)) {
            // 正常签到 (13:50-14:20)
            if (isInTimeRange(currentLocalTime, afternoonOpenStart, afternoonNormalEnd)) {
                stuAttendance.setAfternoonSignIn(1); // 正常签到
            }
            // 迟到 (14:20-14:40)
            else if (isInTimeRange(currentLocalTime, afternoonLateStart, afternoonLateEnd)) {
                stuAttendance.setAfternoonSignIn(2); // 迟到
            }
            stuAttendance.setAfternoonSignInTime(captureTime);
        }
        
        // 晚上签退判断 (17:50-22:00)
        else if (isInTimeRange(currentLocalTime, eveningOpenStart, eveningOpenEnd)) {
            stuAttendance.setEveningSignOut(1); // 正常签退
            stuAttendance.setEveningSignOutTime(captureTime);
        }

        stuAttendance.setCreateBy("设备自查");
        stuAttendance.setUpdateBy("设备自查");
        return stuAttendance;
    }
    
    /**
     * 判断时间是否在指定范围内
     * 
     * @param time 要判断的时间
     * @param startTime 开始时间 (HH:mm格式)
     * @param endTime 结束时间 (HH:mm格式)
     * @return 是否在时间范围内
     */
    private boolean isInTimeRange(LocalTime time, String startTime, String endTime) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
        LocalTime start = LocalTime.parse(startTime, formatter);
        LocalTime end = LocalTime.parse(endTime, formatter);
        
        // 判断时间是否在范围内 (包含开始时间，不包含结束时间)
        return (time.equals(start) || time.isAfter(start)) && time.isBefore(end);
    }

    /**
     * 判断学生的考勤记录是否存在
     *
     * @param sa
     * @return
     */
    @Override
    public Boolean ifSaExist(StuAttendance sa) {
        StuAttendance stuAttendance = stuAttendanceMapper.selectStuAttendanceByPidAndRecordDate(sa.getPid(),sa.getRecordDate());

        if(stuAttendance != null){
            return true ;
        }else{
            return false;
        }

    }

}
